package com.globallogic.vkulyk.SSHTool;

import org.junit.runner.RunWith;
import org.junit.*;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.core.classloader.annotations.*;
import org.powermock.api.mockito.PowerMockito;
import org.mockito.*;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ CLIUserDataModeHandler.class })
public class Unit_CLIUserDataModeHandler extends SSHToolTester {

	@Before
	public void setup() {
		setVarsFromPropertiesFile("testData/testing.properties");
	}

	@Test
	public void shouldInstantiateCommandExecutorWithCorrectArgsAndCallExecute_whenCalledWithCommandExecutionArgs()
			throws Exception {
		// given
		CommandExecutor mockedCommandExecutor = Mockito
				.mock(CommandExecutor.class);
		PowerMockito
				.whenNew(CommandExecutor.class)
				.withArguments(Mockito.anyString(), Mockito.anyInt(),
						Mockito.anyString(), Mockito.anyString(),
						Mockito.anyString()).thenReturn(mockedCommandExecutor);
		String[] args = { user + ":" + password + "@" + host + ":" + port,
				"-c", command };

		// when
		new CLIUserDataModeHandler(args).run();

		// then
		PowerMockito.verifyNew(CommandExecutor.class).withArguments(
				Mockito.eq(host), Mockito.eq(port), Mockito.eq(user),
				Mockito.eq(password), Mockito.eq(command));
		Mockito.verify(mockedCommandExecutor).execute();
	}

	@Test
	public void shouldInstantiateFilePutterWithCorrectArgsAndCallExecute_whenCalledWithFilePutterArgs()
			throws Exception {
		// given
		FilePutter mockedFilePutter = Mockito.mock(FilePutter.class);
		PowerMockito
				.whenNew(FilePutter.class)
				.withArguments(Mockito.anyString(), Mockito.anyInt(),
						Mockito.anyString(), Mockito.anyString(),
						Mockito.anyString(), Mockito.anyString())
				.thenReturn(mockedFilePutter);
		String[] args = { user + ":" + password + "@" + host + ":" + port,
				"-put", srcFileForPut, dstDirForPut };

		// when
		new CLIUserDataModeHandler(args).run();

		// then
		PowerMockito.verifyNew(FilePutter.class).withArguments(
				Mockito.eq(host), Mockito.eq(port), Mockito.eq(user),
				Mockito.eq(password), Mockito.eq(srcFileForPut),
				Mockito.eq(dstDirForPut));
		Mockito.verify(mockedFilePutter).execute();
	}

	@Test
	public void shouldInstantiateFileGetterWithCorrectArgsAndCallExecute_whenCalledWithFileGetterArgs()
			throws Exception {
		// given
		FileGetter mockedFileGetter = Mockito.mock(FileGetter.class);
		PowerMockito
				.whenNew(FileGetter.class)
				.withArguments(Mockito.anyString(), Mockito.anyInt(),
						Mockito.anyString(), Mockito.anyString(),
						Mockito.anyString(), Mockito.anyString())
				.thenReturn(mockedFileGetter);
		String[] args = { user + ":" + password + "@" + host + ":" + port,
				"-get", srcFileForGet, dstDirForGet };

		// when
		new CLIUserDataModeHandler(args).run();

		// then
		PowerMockito.verifyNew(FileGetter.class).withArguments(
				Mockito.eq(host), Mockito.eq(port), Mockito.eq(user),
				Mockito.eq(password), Mockito.eq(srcFileForGet),
				Mockito.eq(dstDirForGet));
		Mockito.verify(mockedFileGetter).execute();
	}

	@Test
	public void shouldInstantiateScriptExecutorWithCorrectArgsAndCallExecute_whenCalledWithScriptExecutionArgs()
			throws Exception {
		// given
		ScriptExecutor mockedScriptExecutor = Mockito
				.mock(ScriptExecutor.class);
		PowerMockito
				.whenNew(ScriptExecutor.class)
				.withArguments(Mockito.anyString(), Mockito.anyInt(),
						Mockito.anyString(), Mockito.anyString(),
						Mockito.anyString()).thenReturn(mockedScriptExecutor);
		String[] args = { user + ":" + password + "@" + host + ":" + port,
				"-s", script };

		// when
		new CLIUserDataModeHandler(args).run();

		// then
		PowerMockito.verifyNew(ScriptExecutor.class).withArguments(
				Mockito.eq(host), Mockito.eq(port), Mockito.eq(user),
				Mockito.eq(password), Mockito.eq(script));
		Mockito.verify(mockedScriptExecutor).execute();
	}
}
